package com.xhwl.logistics.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Joiner;


import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;

/**
 * 签名工具 keytop&bsgoal
 *
 * @author
 * @date 2020/3/6
 */
public class SignUtils {





    /**
     * 对象生成Json对象
     * @param o
     * @return
     */
    public static JSONObject generateJsonObject(Object o) {
        String jsonString = JSON.toJSONString(o);
        JSONObject jsonObject = JSON.parseObject(jsonString);
        return jsonObject;
    }
    /**
     * 参数签名
     * 示例：
     * 参数对象：{"amount":100,"orderNo":"闽C12345","payTime":"2020-03-06 10:57:22","freeDetail":"[{\"code\":\"\",\"money\":100,\"time\":0,\"type\":0}]","paySource":"85d15350778b11e9bbaa506b4b2f6421","outOrderNo":"T20200306124536001","parkId":"1000001","payableAmount":200,"reqId":"5be4e3e6d5704a7d91ccbd9731d970f5","payType":1006,"payMethod":6,"appId":"85d15350778b11e9bbaa506b4b2f6421","freeTime":0,"paymentExt":"{\"deviceNo\":\"123456\"}","freeMoney":100,"ts":1583744086841}
     * url拼接：amount=100&freeDetail=[{"code":"","money":100,"time":0,"type":0}]&freeMoney=100&freeTime=0&orderNo=闽C12345&outOrderNo=T20200306124536001&parkId=1000001&payMethod=6&paySource=85d15350778b11e9bbaa506b4b2f6421&payTime=2020-03-06 10:57:22&payType=1006&payableAmount=200&paymentExt={"deviceNo":"123456"}&reqId=5be4e3e6d5704a7d91ccbd9731d970f5&ts=1583744086841&EED96C219E83450A
     * 签名结果：B19F7863ADCC8B5442A757AC7B90F6AC
     *
     * @param requestBody 参数对象
     * @param appSecret   秘钥
     * @return
     */
    public static String paramsSign(JSONObject requestBody, String appSecret) {

        TreeMap<String, String> params = new TreeMap<>();
        //过滤掉key，appId字段，空属性及Map或List等复杂对象
        requestBody.entrySet().stream().filter(
                p -> !"key".equals(p.getKey())
                        && !"appId".equals(p.getKey())
                        && p.getValue() != null
                        && !(p.getValue() instanceof Map)
                        && !(p.getValue() instanceof Iterable))
                .forEach(p -> {
                    if (!"".equals(p.getValue())) {
                        params.put(p.getKey(), p.getValue().toString());
                    }
                });
        //拼接appSecret
        String temp = Joiner.on("&").withKeyValueSeparator("=").join(params).concat("&").concat(appSecret);
        return md5(temp).toUpperCase();
    }

    /**
     * 对文本执行 md5 摘要加密, 此算法与 mysql,JavaScript生成的md5摘要进行过一致性对比.
     *
     * @param plainText
     * @return 返回值中的字母为小写
     */
    private static String md5(String plainText) {
        if (null == plainText) {
            plainText = "";
        }
        String mD5Str = null;
        try {
            // JDK 支持以下6种消息摘要算法，不区分大小写
            // md5,sha(sha-1),md2,sha-256,sha-384,sha-512
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(plainText.getBytes(StandardCharsets.UTF_8));
            byte[] b = md.digest();
            int i;
            StringBuilder builder = new StringBuilder(32);
            for (byte value : b) {
                i = value;
                if (i < 0) {
                    i += 256;
                }
                if (i < 16) {
                    builder.append("0");
                }
                builder.append(Integer.toHexString(i));
            }
            mD5Str = builder.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return mD5Str;
    }

    /**
     *   请求博思高接口根据参数生成签名并最终生成请求接口的json字符串
     * @param o
     * @param appSecret
     * @return String
     */
    public static Map<String, String> mapWithSignature(Object o, String appSecret) {
        JSONObject requestBody = JSONObject.parseObject(JSON.toJSONString(o));
        List<String> list = new ArrayList<>();
        //参数添加密钥
        requestBody.put("Secretkey",appSecret);
        //过滤空属性及一些非必要参数
        JSONObject jsonObject = new JSONObject();
        requestBody.entrySet().stream().filter(
                p -> p.getValue() != null)
                .forEach(p -> {
                    StringBuilder builder = new StringBuilder();
                    String param = builder.append(p.getKey()).append("=").append(p.getValue()).toString();
                    list.add(param);
                    jsonObject.put(p.getKey(),p.getValue());

                });
        //字典顺序排序
        Collections.sort(list);
        //将集合元素以”&”符号连接成字符串
        String arrstring = String.join("&", list);
        //使用SHA1数字签名算法
        String sign = EncryptUtils.sha(arrstring);
        jsonObject.put("Sign",sign);
        jsonObject.remove("Secretkey");
        String jsonStr = jsonObject.toJSONString();
        Map<String, String> map = new HashMap<>();
        map.put("data",jsonStr);
        return map;

    }

    public static void main(String[] args) {

        String text="{\"reqId\":\""+ System.currentTimeMillis()+"\",\"serviceCode\":\"payParkingFee\",\"key\":\"FBD4C0887171A4FD47CCBC2D170349F8\",\"appId\":\"10031\",\"ts\":\""+ System.currentTimeMillis()+"\",\"parkId\":\"592011253\",\"orderNo\":\"212232978410701\",\"payableAmount\":4700,\"amount\":4700,\"payType\":5,\"payMethod\":4,\"freeMoney\":0,\"freeTime\":0}";
        System.out.println("text = " + text);
        JSONObject jsonObject = JSON.parseObject(text);
        String s = paramsSign(jsonObject, "9d682649d9f64faeb5e4477a8e27858e");
        System.out.println("s = " + s);
        System.out.println("System.currentTimeMillis() = " + System.currentTimeMillis());

        int left=1;int right=3;
        int mid=(left-right)/2;
        System.out.println("mid = " + mid);

        //CardDTO cardDTO=new CardDTO();
        //ParkingLotDTO parkingLotDTO = new ParkingLotDTO();
        //cardDTO.setParkingId("5002779523681665763").setAccessCode("50202212-84f0-11e8-8d22-00163e0c01c9").setSignType("SHA1").setBusinessCode("CardTypeGetList_001")
        //        .setCompanyId("5713831726460572114");
       /* CarDTO carDTO = new CarDTO();
        carDTO.setParkingId("5002779523681665763").setAccessCode("50202212-84f0-11e8-8d22-00163e0c01c9").setSignType("SHA1").setCompanyId("5713831726460572114").setBusinessCode("MonthCarAdd_001");
        carDTO.setPlateNumber("粤A63266").setOwnerName("黄澈").setMobile("18389379711").setCardTypeId("4749087519286086313").setBeginDate("2021-08-23 00:00:00").setEndDate("2021-09-23 00:00:00");
        Map<String, String> map = mapWithSignature(carDTO, "50402239-84f0-11e8-8d22-00163e0c01c9");
        String post1 = HttpUtils.post("http://csykt.bsgoal.net.cn:8086/APPAPI/OISParkingV2", map);
        System.out.println("post = " + post1);*/
        //{"VillageNo":"123","CompanyID":"5713831726460572114","BusinessCode":"ParkinfoGetList_001","AccessCode":"50202212-84f0-11e8-8d22-00163e0c01c9","Sign":"0d5545824ed94e56fe02360f53efe3fec410563f","SignType":"SHA1"}
        //data -> {"CompanyID":"5713831726460572114","BusinessCode":"CardTypeGetList_001","AccessCode":"50202212-84f0-11e8-8d22-00163e0c01c9","Sign":"756a6f14d51551bfdfdebd259fbe164a17ba33cf","SignType":"SHA1","ParkingID":"5002779523681665763"}
        //data -> {"CompanyID":"5713831726460572114","BusinessCode":"CardTypeGetList_001","AccessCode":"50202212-84f0-11e8-8d22-00163e0c01c9","Sign":"7f79d87c604e5ecd3c4a415b1b84784abda08e46","SignType":"SHA1","ParkingID":"5002779523681665763"}
        //{"OwnerName":"黄澈","PlateNumber":"粤A632566","CompanyID":"5713831726460572114","BusinessCode":"MonthCarAdd_001","AccessCode":"50202212-84f0-11e8-8d22-00163e0c01c9","EndDate":"2021-08-23 00:00:00","Mobile":"18389379711","BeginDate":"2021-07-23 00:00:00","CardTypeID":"4749087519286086313","Sign":"e5b9b3a56ae4991073f5764d443d27b8774bd128","SignType":"SHA1","ParkingID":"5002779523681665763"}
        //{"OwnerName":"黄澈","PlateNumber":"粤A65689","CompanyID":"5713831726460572114","BusinessCode":"StoreCarAdd_001","AccessCode":"50202212-84f0-11e8-8d22-00163e0c01c9","EndDate":"","Mobile":"18389379711","BeginDate":"","CardTypeID":"4810886049929591091","Sign":"05c22ace0e2cc9a18cc33ef7079609b7c14da77f","SignType":"SHA1","ParkingID":"5002779523681665763"}
        LinkedList<Object> objects = new LinkedList<>();
    }

}